package com.wsx.ones.gateway.server;

import com.wsx.ones.gateway.core.config.RouterConfig;
import com.wsx.ones.gateway.remote.netty.NettyServerConfig;
import com.wsx.ones.gateway.server.config.GatewayManager;
import com.wsx.ones.gateway.utils.CommandLine;
import com.wsx.ones.gateway.utils.CommandLineUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author wangshuaixin
 * @Title: com.wsx.ones.gateway.server.GatewayServerStartup
 * @Description: startup server
 * @date 2019/07/16
 */
public class GatewayServerStartup {

    private static final Logger log = LogManager.getLogger(GatewayServerStartup.class);


    private static CommandLine commandLine;


    public static void main(String[] args) {
        start(createGatewayServer(args));
    }


    /**
     * create server
     * @param args
     * @return
     */
    public static GatewayServer createGatewayServer(String[] args) {

        try {
            final GatewayConfig gatewayConfig = new GatewayConfig();
            final NettyServerConfig nettyServerConfig = new NettyServerConfig();
            final RouterConfig routerConfig = new RouterConfig();

            //解析命令行参数获得配置文件
            commandLine = CommandLineUtils.parse(args);

            //
            GatewayManager gatewayManager = new GatewayManager();
            if (commandLine.contains("file")) {
                gatewayManager.setFileName(commandLine.getValue("file"));
            }
            if (!gatewayManager.load()) {
                log.error("gateway load file fail");
                System.exit(-1);
            }
            gatewayManager.processGatewayConfig(gatewayConfig);
            gatewayManager.processNettyServerConfig(nettyServerConfig);
            gatewayManager.processRouterConfig(routerConfig);


            final GatewayServer gatewayServer = new GatewayServer(gatewayConfig, nettyServerConfig, routerConfig);

            boolean init = gatewayServer.initialize();
            if (!init) {
                log.error("gateway server initialize fail");
                System.exit(-1);
            }

            //
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

                private volatile boolean shutdown = false;
                private AtomicInteger shutdownTimes = new AtomicInteger(0);

                @Override
                public void run() {
                    synchronized (this) {
                        log.info("gateway server shutdown times is " + shutdownTimes.incrementAndGet());
                        if (!shutdown) {
                            this.shutdown = true;
                            long start = System.currentTimeMillis();
                            gatewayServer.shutdown();
                            log.info("gateway server shutdown cast time is " + (System.currentTimeMillis() - start));
                        }
                    }
                }
            }, "shutdown-gateway"));

            return gatewayServer;
        } catch (Exception e) {
            log.error("create gateway server error", e);
            System.exit(-1);
        }
        return null;
    }

    public static GatewayServer start(GatewayServer gatewayServer) {
        try {
            gatewayServer.start();

            return gatewayServer;
        } catch (Exception e) {
            log.error("start gateway server error", e);
            System.exit(-1);
        }
        return null;
    }
}
